package token

import (
	"crypto/md5"
	"fmt"
	"io"
	"math/rand"
	"time"
)

type User struct {
	ID    string
	Timer *time.Timer
}

var tToken map[string]*User = make(map[string]*User)
var maxLiveTime time.Duration = time.Hour * 24 // tToken更新时间暂定为24小时
var lock chan bool = make(chan bool, 1)

const randStringLen = 16

func randString() string {
	str := make([]byte, randStringLen)
	for i := 0; i < randStringLen; i++ {
		str[i] = byte(rand.Uint32() & ((1 << 7) - 1))
	}
	return string(str)
}

func New(userID string, token *string, writetToken func()) {
	lock <- true
	delete(tToken, *token)
	hash := md5.New()
	io.WriteString(hash, userID)
	io.WriteString(hash, time.Now().String())
	*token = fmt.Sprintf("%x", hash.Sum(nil))
	timer := time.AfterFunc(maxLiveTime, func() { New(userID, token, writetToken) })
	tToken[*token] = &User{
		ID:    userID,
		Timer: timer,
	}
	<-lock
	writetToken()
}

func Del(token string) {
	lock <- true
	user := tToken[token]
	user.Timer.Stop()
	delete(tToken, token)
	<-lock
}

func GetUser(token string) (user *User, existToken bool) {
	lock <- true
	defer func() {
		<-lock
	}()
	user, existToken = tToken[token]
	return user, existToken
}
